package org.tzeng.glwj.datam;

import org.tzeng.glwj.datag.GenerateDataSet;
import org.tzeng.glwj.datag.Item;
import org.tzeng.glwj.datag.ItemRanges;
import org.tzeng.glwj.datag.Range;

import java.util.*;

/**
 * Created by tzeng on 2016-03-31.
 */
public class Arguments {
    /*每个项目内容长度限制*/
    public static final int ITEM_LENGTH_MAX = 4;
    /*每个项目基本构成元素（a-z）最大26个*/
    public static final int ITEMSET_LENGTH_MAX = 6;
    /*区间范围限制*/
    public static final int RANGE_DOWN = 20;
    public static final int RANGE_UP = 500;
    /*区间扩展因子范围限制*/
    public static final double EXPANDED_FACTOR = 0.1;
    public static final double EXPANDED_FACTOR_DOWN = 0.5;
    public static final double EXPANDED_FACTOR_UP = 1.5;
    /*项目集最大值*/
    public static final int ITEMSET_SIZE_MAX = 10;

    public static void main(String[] args){
        GenerateDataSet generate = new GenerateDataSet();
        List<Item> db = generate.GenerateDB(ITEM_LENGTH_MAX, ITEMSET_LENGTH_MAX, RANGE_DOWN, RANGE_UP, ITEMSET_SIZE_MAX);
        System.out.println("source----------------------");
        for(int i = 0,size = db.size();i<size;i++){
            System.out.println(db.get(i).getContent() + "\t: \t["+ db.get(i).getStart()+", "+db.get(i).getEnd() + "]");
        }
        expandRange(db, EXPANDED_FACTOR);
        System.out.println("expand----------------------");
        for(int i = 0,size = db.size();i<size;i++){
            System.out.println(db.get(i).getContent() + "\t: \t["+ db.get(i).getStart()+", "+db.get(i).getEnd() + "]");
        }

        Map<String, ItemRanges> map = new HashMap<String, ItemRanges>();

        // 得到一阶候选键  {a,d,f} 和 项目集字符串最大长度 eg.abef => max = 4
        String keys = "";
        int max = 0;
        for (Item item : db){
            keys += item.getContent();
            if (item.getContent().length() > max)
                max = item.getContent().length();
        }
        keys = removeSameString(keys);
        Object[] items = {};
        for (int i = 0; i < keys.length(); i++) {
            items[i] = keys.charAt(i) + "";
        }

        // 将 key即 {a,b} 或 {ab, ac, cd} 对应的有效时间加入到map，得到支持区间和支持数
        for (int k = 1; k <= max; k++) {
            for (int j = 0; j < items.length; j++) {
                for (Item item : db) {
                    if(isContain(item.getContent(), items[j].toString())){
                        if (map.containsKey(items[j].toString())){
                            List<Range> r = map.get(items[j].toString()).getRanges();
                            r.add(new Range(item.getStart(),item.getEnd()));
                        }else{
                            map.put(items[j].toString(), new ItemRanges(items[j].toString(), new Range(item.getStart(),item.getEnd())));
                        }
                    }
                }
            }
            //合并，计算支持度
            mergeRange(map);
            //输出 size >= 2的，将key保存到items



            // 计算机下一阶的key
            items = getItems(items, k + 1);
            // 清空map
            map.clear();
        }
    }

    /**
     * 由低一阶生成高一阶项目集合
     * order = 2 时，{a,b,c} => {ab,ac,bc}
     * @param items 低阶项目集合
     * @param order 阶 (order > 2)
     * @return
     */
    public static Object[] getItems(Object[] items, int order) {
        List<String> lists = new ArrayList<String>();
        for (int i = 0; i < items.length; i ++){
            for (int j = i + 1; j < items.length; j ++){
                String tmp = removeSameString(items[i].toString() + items[j]);
                if (tmp.length() == order && !lists.contains(tmp))
                    lists.add(tmp);
            }
        }
        return lists.toArray();
    }

    /**
     * 去除字符串中连续重复字符串
     * "22233333fff" => "23f"
     * @param s
     * @return
     */
    public static String removeRepeatedChar(String s) {
        if (s == null)
            return s;
        StringBuilder sb = new StringBuilder();
        int i = 0, len = s.length();
        while (i < len) {
            char c = s.charAt(i);
            sb.append(c);
            i++;
            while (i < len && s.charAt(i) == c) {
                i++;
            }
        }
        return sb.toString();
    }

    /**
     * 去除字母组成的重复字符串，返回的字符串按字母顺序排列
     * abcaassd => abcds
     * @param str
     * @return
     */
    public static String removeSameString(String str) {
        int[] bit = new int[26];
        for (int i = 0; i < str.length(); i++) {
            int index = str.charAt(i) - 97;
            bit[index] = 1;
        }

        String sb = "";
        for (int i = 0; i < 26; i++) {

            if (bit[i] == 1)
                sb += ((char) (i + 97) + "");
        }
        return sb;
    }

    public static void expandRange(List<Item> db, double factor){
        for (int i = 0; i < db.size(); i++) {
            Item item = db.get(i);
            item.setStart(item.getStart() - (int) (item.getStart() * factor));
            item.setEnd((int) (item.getEnd() * factor) + item.getEnd());
        }
    }

    public static boolean isContain(String content, String substr){
        int ilen = substr.length(), index = 0;
        for (int i = 0; i < ilen; i++) {
            if(content.indexOf(substr.charAt(i)) >= 0) {
                index++;
            }
        }

        return index == ilen;
    }

    public static void mergeRange(Map<String, ItemRanges> map){
        for (String key : map.keySet()) {
            List<Range> ranges = map.get(key).getRanges();
            //


            int[] flags = new int[RANGE_UP];
            for(Range r : ranges){
                for (int i = r.getStart(); i < (r.getEnd() > RANGE_UP ? RANGE_UP : r.getEnd()); i++) {
                    flags[i] ++;
                }
            }



        }
    }
}
